/**
 * node中的文件模块, 读取文件
 * fs.readFile(path, [, options],callback)
 * 参数1: path 文件路径 必选参数
 * 参数2: options 可选参数 表示读取文件的编码格式 默认为null
 * 参数3: callback 回调函数, 读取文件完成后执行的回调函数 必选参数
 * 
 * fs模块 - 路径动态拼接的问题: 
 * 如果提供的操作路径是以 ./ 或 ../ 开头的相对路径时，很容易出现路径动态拼接错误的问题。
 * 解决方案: 在使用 fs 模块操作文件时，直接提供完整的路径，不要提供 ./ 或 ../ 开头的相对路径，从而防止路径动态拼接的问题
 */

/**
 * fs.readFile和fs.readFileSync的区别
 * fs.readFile是异步读取文件, 读取文件时不会阻塞后续代码执行
 * fs.readFileSync是同步读取文件, 读取文件时会阻塞后续代码执行
 */
const fs = require('fs');
const path = require('path');

// 创建大数据
fs.writeFileSync(path.join(__dirname, 'bigData.txt'), new Array(1024 * 1024).fill('hello').join(' '));
/**
 * 同步读取文件
 */

function readFile() {
    const data = fs.readFileSync(path.join(__dirname, 'bigData.txt'))
    console.log('同步读取文件:>>> ')
}

async function readFileSync() {
    // fs.readFile(path.join(__dirname, 'bigData.txt'), 'utf-8',(err, data) => {
    //     if (err) {
    //         console.log('读取文件失败', err);
    //     } else {
    //         console.log('异步读取文件:>>> ', data);
    //     }
    // });

    // fs.promises.readFile 返回一个 Promise 对象
    try {
        const data = await fs.promises.readFile(path.join(__dirname, 'bigData.txt'), 'utf-8')
        console.log('异步读取文件:>>> ');
    } catch(err) {
        console.log('读取文件失败', err);
    }
}
readFile()
readFileSync()
console.log('是否阻塞后续代码执行')

/**
 * 以上三种读取文件的方式都是在返回数据之前将文件的全部内容读取到内存中, 如果文件过大, 会导致内存溢出
 * 为了解决这个问题, 可以使用流的方式读取文件
 * 流的方式读取文件, 会将文件分成多个小块, 逐步读取, 从而避免一次性将文件的全部内容读取到内存中
 */

/************************************ 流的方式读取文件 ************************************/
fs.createReadStream(path.join(__dirname, 'bigData.txt'), {})
.on('data', (chunk) => {
    console.log('流的方式读取文件:>>> ');
})
.on('end', () => {
    console.log('文件读取完毕');
})
.on('error', (err) => {
    console.log('文件读取失败', err);
})